import collections, os, os.path
import zipfile, requests
from bs4 import BeautifulSoup

class Book(object):
  def __init__(self):
    self.text = collections.OrderedDict()
    self.title = ''
    self.author = ''
    self.cover = ''

  def setTitle(self, title):
    self.title = title

  def setAuthor(self, author):
    self.author = author
  
  def setCover(self, cover):
    self.cover = cover

  def appendText(self, section, text):
    if section in self.text:
      self.text[section] += text
    else:
      self.text[section] = text

imageTotal = 0
total = 0

def download(zipfile, filename, url):
  global imageTotal
  headers = {'Cookie': 'Hm_lvt_acfbfe93830e0272a88e1cc73d4d6d0f=1668230023,1668241009; Hm_lvt_d72896ddbf8d27c750e3b365ea2fc902=1668230023,1668241009; Hm_lpvt_d72896ddbf8d27c750e3b365ea2fc902=1668249547; Hm_lpvt_acfbfe93830e0272a88e1cc73d4d6d0f=1668241029; __vtins__1xpAUPUjtatG3hli=%7B%22sid%22%3A%20%2244354f9f-c0bc-51c1-b37f-1bcf85693799%22%2C%20%22vd%22%3A%201%2C%20%22stt%22%3A%200%2C%20%22dr%22%3A%200%2C%20%22expires%22%3A%201668251338243%2C%20%22ct%22%3A%201668249538243%7D; __51uvsct__1xpAUPUjtatG3hli=1; __51vcke__1xpAUPUjtatG3hli=bdf61955-9f68-5f95-840e-ae0bc16e455a; __51vuft__1xpAUPUjtatG3hli=1668249538245', 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:106.0) Gecko/20100101 Firefox/106.0'}
  with open('OEBPS/images/' + filename, 'wb') as fi:
    fi.write(requests.get(url, headers = headers).content)
  zipfile.write('OEBPS/images/' + filename)
  os.remove('OEBPS/images/' + filename)
  imageTotal += 1
  print('\r已下载 %s 张图片，一共 %s 张图片'%(imageTotal, total), end = '')

def writeFile(zipfile, filename, content):
  with open(filename, 'w') as f:
    f.write(content)
  zipfile.write(filename)
  os.remove(filename)

def toEpub(book, filename):
  global total
  if os.path.isfile('temp-epub'):
    os.remove('temp-epub')
  if not os.path.isdir('temp-epub'):
    os.mkdir('temp-epub')
  with zipfile.ZipFile(filename, 'w', zipfile.ZIP_DEFLATED) as zf:
    os.chdir('temp-epub')
    writeFile(zf, 'mimetype', 'application/epub+zip')
    os.mkdir('META-INF')
    writeFile(zf, 'META-INF/container.xml', '''<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="urn:oasis:names:tc:opendocument:xmlns:container" version="1.0">
  <rootfiles>
    <rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/>
  </rootfiles>
</container>''')
    id = 1
    os.mkdir('OEBPS')
    downPool = []
    os.mkdir('OEBPS/images')
    content = '''<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/">
  <head>
    <meta content="urn:uuid:9bfb698f-dfa3-45ca-bea4-d0fbc2ead4f3" name="dtb:uid"/>
    <meta content="1" name="dtb:depth"/>
    <meta content="0" name="dtb:totalPageCount"/>
    <meta content="0" name="dtb:maxPageNumber"/>
  </head>
  <docTitle>
    <text>''' + book.title + '''</text>
  </docTitle>
  <navMap>
  '''
    content1 = '''<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://www.idpf.org/2007/opf" unique-identifier="bookId" version="2.0">
  <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
    <dc:identifier id="bookId">urn:uuid:9bfb698f-dfa3-45ca-bea4-d0fbc2ead4f3</dc:identifier>
    <dc:language>en</dc:language>
    <dc:title>''' + book.title + '''</dc:title>
    <dc:creator>''' + book.author + '''</dc:creator>
    '''
    if book.cover != '':
      content1 += '<meta content="cover-image" name="cover"/>'
      downPool.append((zf, 'cover', book.cover))
    content1 += '''
  </metadata>
  <manifest>
    <item href="toc.ncx" id="ncx" media-type="application/x-dtbncx+xml"/>
'''
    if book.cover != '':
      content1 += '<item href="images/cover" id="cover-image" />\n'
    content2 = '''  </manifest>
  <spine toc="ncx">
'''
    for k, v in book.text.items():
      soup = BeautifulSoup(v, 'lxml')
      imgs = soup.find_all('img')
      if len(imgs) != 0:
        for item in imgs:
          url = item.attrs['src']
          image = url.split('/')[-1]
          v = v.replace(url, 'images/' + image)
          downPool.append((zf, image, url))
      writeFile(zf, 'OEBPS/' + str(id) + '.xhtml', '''<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
  </head>
  <body>
    <article>
    ''' + v + '''
    </article>
  </body>
</html>''')
      content += '''  <navPoint id="navPoint-''' + str(id) + '''" playOrder="''' + str(id) + '''">
      <navLabel>
        <text>''' + k + '''</text>
      </navLabel>
      <content src="''' + str(id) + '''.xhtml"/>
    </navPoint>
    '''
      content1 += '  <item href="' + \
          str(id) + '.xhtml" id="' + str(id) + \
          '.xhtml" media-type="application/xhtml+xml"/>\n'
      content2 += '  <itemref idref="' + str(id) + '.xhtml"/>\n'
      id += 1
    content += '''  </navMap>
</ncx>'''
    content2 += '''  </spine>
</package>'''
    writeFile(zf, 'OEBPS/toc.ncx', content)
    writeFile(zf, 'OEBPS/content.opf', content1 + content2)
    total = len(downPool)
    for i in downPool:
      download(i[0], i[1], i[2])
  os.rmdir('OEBPS/images')
  os.rmdir('OEBPS')
  os.rmdir('META-INF')
  os.chdir('../')
  os.rmdir('temp-epub')